//: Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"

class Circle {
    final var redius = 0;
    var area: String {
        return "矩形";
    }
}

class Rectangle: Circle {
    
    override var area: String {
        return "长方形";
    }
}
var cir = Circle();
cir.area;
var rec = Rectangle();
rec.area;


class Boss {
//    var employee: Person? = nil;
    init() {
        print("Boss init")
    }
    
    deinit {
        print("Boss deinit")
    }
}

class Person {
    let name: String;
    var boss: Boss? = nil;
    init(name: String) {
        self.name = name;
        print("\(name)开始初始化");
    }
    
    deinit {
        print("\(name)deinit")
    }
}

var p: Person? = Person(name: "Dick");
var boss: Boss? = Boss();
boss = nil
p = nil;
//if let b = boss {
//    b = nil;
//}

// 强引用
// 使用weak关键字 weak var
class Module {
    let name: String
    init(name: String) { self.name = name }
    var sub: SubModule?
    deinit { print("\(name) 主模块") }
}

class SubModule {
    let number: Int
    
    init(number: Int) { self.number = number }
    
    weak var topic: Module?
    
    deinit { print("子模块 topic 数为 \(number)") }
}

var toc: Module?
var list: SubModule?
toc = Module(name: "ARC")
list = SubModule(number: 4)
toc!.sub = list
list!.topic = toc

toc = nil
list = nil


// 闭包强引用
class HTMLElement {
    let name: String
    let text: String?
    
    lazy var asHTML: () -> String = {
        // 使用unowned无主引用防止循环引用
        [unowned self] in
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }
    
    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }
    
    deinit {
        print("\(name) is being deinitialized")
    }
}

// 创建实例并打印信息
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())
paragraph = nil;

class mainClass {
    var no1 : Int // 局部存储变量
    init(no1 : Int) {
        self.no1 = no1 // 初始化
    }
}
class subClass : mainClass {
    var no2 : Int // 新的子类存储变量
    init(no1 : Int, no2 : Int) {
        self.no2 = no2 // 初始化
        super.init(no1:no1) // 初始化超类
    }
    
    override convenience init(no1: Int) {
        self.init(no1: no1, no2: 0);
    }
}

let res2 = subClass(no1: 100);


class SuperClass1 {
    var corners = 4
    var description: String {
        return "\(corners) 边"
    }
}
let rectangle = SuperClass1()
print("矩形: \(rectangle.description)")

class SubClass1: SuperClass1 {
    override init() {  //重载构造器
        super.init()
        corners = 5
    }
}

let subInstance = SubClass1()
print("五角型: \(subInstance.description)")

// 类的可失败构造器
struct Animal {
    let species: String
    init?(species: String) {
        if species.isEmpty { return nil }
        self.species = species
    }
}

//通过该可失败构造器来构建一个Animal的对象，并检查其构建过程是否成功
// someCreature 的类型是 Animal? 而不是 Animal
let someCreature = Animal(species: "")

// 打印 "动物初始化为长颈鹿"
if let giraffe = someCreature {
    print("动物初始化为\(giraffe.species)");
}else {
    print("===");
}

class StudRecord {
    var studname: String!
    init?(studname: String) {
        self.studname = studname
        if studname.isEmpty { return nil }
    }
    
    init!(stuAge: String){
        self.studname = stuAge;
        if stuAge.isEmpty { return nil }
    }

    // Below init error
//    init (stuGender: String) {
//        self.studname = stuGender;
//        if stuGender.isEmpty { return nil }
//    }
    
    
    deinit {
        print("deinit revoke");
        studname = nil;
    }
}
if let stname = StudRecord(studname: "失败构造器") {
    print("模块为 \(stname.studname)")
}

let stnAge = StudRecord(stuAge: "");
stnAge;


// Swift 可选链
class Person1 {
    var res: Residence1?;
}

class Residence1 {
    var numberofRooms = 1;
}

var person = Person1();
//person.res!// Error Occured
let number = person.res?.numberofRooms;

person.res = Residence1();
person.res!.numberofRooms;
person.res?.numberofRooms;
//person.res.numberofRooms;//需要使用!/?解构



